package main

import (
	"fmt"
	"runtime"
	"sync"
)

// Task 任务接口
type Task interface {
	// Execute 执行
	Execute()
	// GetResult 返回结果
	GetResult() string
}

// DoctorTask 医生工作
type DoctorTask struct {
	Wg     *sync.WaitGroup
	Result string
}

func (task *DoctorTask) Execute() {
	task.Result = "医生的工作，诊疗"
	task.Wg.Done()
}

func (task *DoctorTask) GetResult() string {
	return task.Result
}

// WorkerTask 工人工作
type WorkerTask struct {
	Wg     *sync.WaitGroup
	Result string
}

func (task *WorkerTask) Execute() {
	task.Result = "工人的工作，生产"
	task.Wg.Done()
}

func (task *WorkerTask) GetResult() string {
	return task.Result
}

// TeacherTask 老师工作
type TeacherTask struct {
	Wg     *sync.WaitGroup
	Result string
}

func (task *TeacherTask) Execute() {
	task.Result = "老师的工作，教学"
	task.Wg.Done()
}

func (task *TeacherTask) GetResult() string {
	return task.Result
}

type RoutinePool struct {
	//启动的协程数量
	coreNum int
	//任务列表
	TaskList chan Task
}

func (p *RoutinePool) Submit(t Task) {
	p.TaskList <- t
}

func NewPool(core int) *RoutinePool {
	if core <= 0 {
		core = runtime.GOMAXPROCS(0)
	}
	p := &RoutinePool{
		TaskList: make(chan Task),
		coreNum:  core,
	}
	for i := 0; i < core; i++ {
		go func() {
			for task := range p.TaskList {
				task.Execute()
			}
		}()
	}
	return p
}

func main() {
	pool := NewPool(2)

	var wg sync.WaitGroup
	doctorTask := &DoctorTask{Wg: &wg}
	wg.Add(1)
	pool.Submit(doctorTask)

	workerTask := &WorkerTask{Wg: &wg}
	wg.Add(1)
	pool.Submit(workerTask)

	teacherTask := &TeacherTask{Wg: &wg}
	wg.Add(1)
	pool.Submit(teacherTask)

	wg.Wait()

	fmt.Println(doctorTask.GetResult())
	fmt.Println(workerTask.GetResult())
	fmt.Println(teacherTask.GetResult())

}
